package control;

import database.Database;
import java.sql.SQLException;
import java.text.DecimalFormat;
import java.util.ArrayList;
import model.*;

/**
 * Denne klasse håndterer alt der har at gøre med manipulation af databasen i forbindelse med ordrer
 * @author Sonny Sandberg
 */
public abstract class OrderControl 
{
    /**
     * Tilføj Ordre
     * @param Order
     * @return boolean
     * @throws ClassNotFoundException
     * @throws SQLException 
     */
    public static boolean addOrder(Order order) throws ClassNotFoundException, SQLException
    {
        // Tilføj Tombstone delen, hvis den eksisterer
        if (order.getTombStone() != null)
        {
            TombStone tombStone = order.getTombStone();
            int tombStoneAdded = TombStoneControl.addTombStonePart(tombStone);
            if (tombStoneAdded > 0)
            {
                tombStone = model.handlers.TombStoneHandler.getLatestTombStone(tombStone);
            }
        }
        
        // Tilføj ordre
        int orderAdded = addTheOrder(order);
        if (orderAdded > 0)
        {
            // Hent den nye ordre, så der er et id til de næste ting der skal tilføjes
            order = model.handlers.OrderHandler.getLatestOrder(order);
        }
        
        if (order.getId() > 0)
        {
            // Tilføj Kunde og Betaler
            addOrderCustomerRelation(order);
            
            // Tilføj ordrelinier
            addOrderLines(order.getOrderLine());
        }
        
        return true;        
    }
    
    /**
     * Tilføj selve ordre delen
     * @param Order
     * @return int
     * @throws ClassNotFoundException
     * @throws SQLException 
     */
    public static int addTheOrder(Order order) throws ClassNotFoundException, SQLException
    {
        // Sæt pickup date streng til hvad den skal være, i tilfælde af, den ikke er udfyldt i objektet
        String pickup_date = "0000-00-00";
        if (order.getPickup_date().length() == 10)
        {
            // Konvertér fra dd.mm.YYYY til YYYY-mm-dd 
            pickup_date = utility.Converter.dateToMysqlDate(order.getPickup_date());
        }
        
        // Sæt delivery date streng til hvad den skal være, i tilfælde af, den ikke er udfyldt i objektet
        String delivery_date = "0000-00-00";
        if (order.getDelivery_date().length() == 10)
        {
            // Konvertér fra dd.mm.YYYY til YYYY-mm-dd
            delivery_date = utility.Converter.dateToMysqlDate(order.getDelivery_date());
        }
        
        String comment = order.getComment();
        int userID = order.getUser().getId();
        int taxID = order.getProgramValues().getId();
        
        // Selvom dette i databasen er en int, skal vi have en null værdi, i tilfælde af, der ikke er nogen tombStone til ordren
        // Forsøges det at sætte 0 (zero) i stedet, returnerer databasen parent/child constraint fejl
        // En int kan ikke være null i JAVA, der strengen
        String tombStoneID = null;
        
        // Først tjek, at der findes et TombStone objekt
        if (order.getTombStone() != null)
        {
            if (order.getTombStone().getId() != 0)
            {
                tombStoneID = ""+order.getTombStone().getId();
            }
        }
        
        Database db = new Database();
        
        int added = db.manipulateDB("INSERT INTO bs_order (pickup_date, delivery_date, comment, fk_user_id, fk_tax, fk_tombstone_order_id) "
                + "VALUES "
                + "('"+pickup_date+"', '"+delivery_date+"', '"+comment+"', "+userID+", "+taxID+", "+tombStoneID+")");
        
        db.closeDB();
        
        return added;
    }
    
    /**
     * Denne metode sletter ikke ordren som sådan.<br />
     * Den sletter alle ordrerlinier, sætter produkter som værende ikke solgt og sætter ordren som afsluttet<br />
     * En slettet ordre, er altså bare en afsluttet ordre uden solgte produkter
     * @param Order
     * @return boolean
     * @throws ClassNotFoundException
     * @throws SQLException 
     */
    public static boolean deleteOrder(Order order) throws ClassNotFoundException, SQLException
    {
        Database db = new Database();        
        db.manipulateDB("DELETE FROM bs_order_line WHERE fk_order_id = "+order.getId());
        db.manipulateDB("UPDATE bs_order SET finished = 1 WHERE id = "+order.getId());
        
        for (OrderLine value : order.getOrderLine())
        {
            Product product = value.getProduct();
            if (product.isRemainAfterSale() == false)
            {
                db.manipulateDB("UPDATE bs_product SET sold = 0 WHERE id = "+product.getId());
            }
        }
        
        db.closeDB();
        
        return true;
    }
    
    /**
     * Tilføj Fakturadato
     * @param Order
     * @return int
     * @throws ClassNotFoundException
     * @throws SQLException 
     */
    public static int addInvoiceDate(Order order) throws ClassNotFoundException, SQLException
    {
        Database db = new Database();
            int altered = db.manipulateDB("UPDATE bs_order SET invoice_date = NOW() WHERE id = "+order.getId());
        db.closeDB();
        
        return altered;
    }
    
    /**
     * Tilføj Ordre/Kunde relation
     * @param Order
     * @return int
     * @throws ClassNotFoundException
     * @throws SQLException 
     */
    public static int addOrderCustomerRelation(Order order) throws ClassNotFoundException, SQLException
    {
        Database db = new Database();
        
        int added = 0;
        for (int i = 0; i < order.getCustomerSpecified().length; i++)
        {
            db.manipulateDB("INSERT INTO bs_order_customer (fk_order_id, fk_customer_id, order_or_payer) "
                + "VALUES "
                + "('"+order.getId()+"', "+order.getCustomerSpecified()[i].getCustomerName().getId()+", "+i+")");  
            added++;
        }        
        db.closeDB();
        
        return added;
    }
    
    /**
     * Tilføj ordrelinier
     * @param ArrayList<OrderLine>
     * @throws ClassNotFoundException
     * @throws SQLException 
     */
    public static void addOrderLines(ArrayList<OrderLine> orderLine) throws ClassNotFoundException, SQLException
    {
        Database db = new Database();
        
        for (int i = 0; i < orderLine.size(); i++)
        {
            db.manipulateDB("INSERT INTO bs_order_line (amount, unit_price, fk_product_id, fk_order_id) VALUES ('"+orderLine.get(i).getAmount()+"', '"+orderLine.get(i).getUnitPrice()+"', '"+orderLine.get(i).getProduct().getId()+"', '"+orderLine.get(i).getOrder().getId()+"')");            
        }        
        db.closeDB();
    }
    
    /**
     * Begfør betaling
     * @param Order
     * @param String
     * @return
     * @throws ClassNotFoundException
     * @throws SQLException 
     */
    public static int receivePayment(Order order, String payment) throws ClassNotFoundException, SQLException
    {
        Database db = new Database();
        
        payment = payment.replace(",", ".");                                    // Fjern komma fra strengen og sæt punktum i stedet
        double pay = Double.parseDouble(payment);                               // Omdan streng til double
        
        DecimalFormat df = new DecimalFormat("#.##");
        double toPay = order.totalPriceVat() - order.getPayment_received();     // Hvor meget skal der betales i alt
        String toReceive = df.format(toPay);                                    // Lav en formateret streng med tallet, så det nu kun har to cifre efter komma
        toReceive = toReceive.replace(",", ".");                                // Fjern komma fra strengen og sæt punktum i stedet
        toPay = Double.parseDouble(toReceive);                                  // Omdan streng til double
        
        // Hvis det fulde manglende beløb eller mere er modtaget, afslut ordren
        if (pay >= toPay)
        {
            pay = toPay;
            db.manipulateDB("UPDATE bs_order SET finished = 1 WHERE id = "+order.getId());    
        }
        
        // Om ordren er afsluttet eller ej, begfør betaling
        int altered = db.manipulateDB("UPDATE bs_order SET payment_received = payment_received + "+pay+" WHERE id = "+order.getId());        
        db.closeDB();
        
        return altered;
    }
}